#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "DHT11.h"

/**
  * @brief	DHT11拉高数据线函数
  * @param	无
  * @retval	无
  */
void DHT11_Mode_OutH(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_8);
}

/**
  * @brief	DHT11拉低数据线函数
  * @param	无
  * @retval	无
  */
void DHT11_Mode_OutL(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_8);
}

/**
  * @brief	DHT11读取引脚电平
  * @param	无
  * @retval	读取到的引脚电平状态 0/1
  */
uint8_t DHT11_Mode_R_IN(void)
{
	return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8);
}

/**
  * @brief	DHT11初始化函数
  * @param	无
  * @retval	无
  */
void DHT11_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	DHT11_Mode_OutH();
}

/**
* @brief	DHT11将通信引脚配置为推挽输出
  * @param	无
  * @retval	无
  */
void DHT11_Out_PP(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/**
* @brief	DHT11将通信引脚配置为上拉输入
  * @param	无
  * @retval	无
  */
void DHT11_IPU(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/**
* @brief	DHT11获取一个字节数据
  * @param	无
  * @retval	读取到的一个字节数据
  */
uint8_t DHT11_GetByte(void)
{
	uint8_t i = 0;
	uint8_t Byte = 0x00;
	
	for(i = 0;i < 8;i++)
	{
		if(DHT11_Mode_R_IN() == 0)
		{
			while(DHT11_Mode_R_IN() == 0);
			Delay_us(40);

			if(DHT11_Mode_R_IN() == 1)
			{
				Byte |= (0x80>>i);
				
				while(DHT11_Mode_R_IN() == 1);
			}
			else
			{
				Byte &= ~(0x80>>i);
			}
		}
	}
	
	return Byte;
}

/**
* @brief	DHT11读取4个字节温湿度+一个字节校验数据
  * @param	无
  * @retval	是否成功读取数据SUCCESS/ERROR
  */
uint8_t DHT11_HumiAndTemp_Data(DHT11_Humi_Temp *DHT11_Data)
{
	DHT11_Init();
	
	DHT11_Mode_OutL();
	Delay_ms(20);
	DHT11_Mode_OutH();
	Delay_us(30);
	DHT11_IPU();
	
	if(DHT11_Mode_R_IN() == 0)
	{
		while(DHT11_Mode_R_IN() == 0);
		while(DHT11_Mode_R_IN() == 1);
		
		DHT11_Data->Humi_Int = DHT11_GetByte();
		DHT11_Data->Humi_Dec = DHT11_GetByte();
		DHT11_Data->Temp_Int = DHT11_GetByte();
		DHT11_Data->Temp_Dec = DHT11_GetByte();
		DHT11_Data->Check = DHT11_GetByte();
		
		Delay_us(50);
		DHT11_Out_PP();
		DHT11_Mode_OutH();
		
		if(DHT11_Data->Check == DHT11_Data->Humi_Int+DHT11_Data->Humi_Dec+DHT11_Data->Temp_Int+DHT11_Data->Temp_Dec)
		{
			return SUCCESS;
		}
		else
		{
			return ERROR;
		}
	}
	else
	{
		return ERROR;
	}
}




//#include "stm32f10x.h"                  // Device header
//#include "Delay.h"
//#include "DHT11.h"

//static void DHT11_GPIO_outL(void)
//{
//	GPIO_ResetBits(GPIOA, GPIO_Pin_8);
//}

//static void DHT11_GPIO_outH(void)
//{
//	GPIO_SetBits(GPIOA, GPIO_Pin_8);
//}

//void DHT11_Init(void)
//{
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//	
//	GPIO_InitTypeDef GPIO_InitStructure;
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA, &GPIO_InitStructure);
//	
//	DHT11_GPIO_outH();               // 拉高GPIOA8
//}

//static void DHT11_Mode_IPU(void)
//{
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//	
//	GPIO_InitTypeDef GPIO_InitStructure;
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA, &GPIO_InitStructure);
//}

//static void DHT11_Mode_Out_PP(void)
//{
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//	
//	GPIO_InitTypeDef GPIO_InitStructure;
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA, &GPIO_InitStructure);
//}

//static uint8_t DHT11_GPIO_IN(void)
//{
//	return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8);
//}

//static uint8_t DHT11_ReadByte ( void )
//{
//	uint8_t i = 0;
//	uint8_t Temp = 0x00;
//	
//	for(i = 0;i < 8; i++)
//	{
//		while(DHT11_GPIO_IN()==Bit_RESET);		//首先跳过数据的低电平
//		Delay_us(40);							//延时40us用来区分数据0和1--0是26-28us---1是70us的高电平
//		
//		if(DHT11_GPIO_IN()==Bit_SET)/* 40us后仍为高电平表示数据“1” */
//		{
//			Temp |= (0x80>>i);  //MSB先行，把数据1放到临时变量的i位
//			
//								//既然进入了if语句就说明是数据1，高电平到这里还剩余30us
//			/* 等待数据1的高电平结束 */
//			while(DHT11_GPIO_IN()==Bit_SET);
//		}
//		else	 // 40us后为低电平表示数据“0”
//		{			   
//			Temp &= ~(0x80>>i); //MSB先行，把数据0放到临时变量的i位
//		}
//	}
//	
//	return Temp;
//	
//}

//uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
//{
////	DHT11_Mode_Out_PP();
//	DHT11_Init();//首先改为输出模式
//	
//	DHT11_GPIO_outL();//主机拉低数据线
//	Delay_ms(18);
//	
//	DHT11_GPIO_outH();//主机拉高数据线
//	Delay_us(30);
//	
//	DHT11_Mode_IPU();//把GPIO改为输入模式
//	
//	if(DHT11_GPIO_IN()==0)			//读取GPIO电平，如果是低电平证明从机应答
//	{
//		while(DHT11_GPIO_IN()==0);	//等待从机应答低电平结束，80us
//		while(DHT11_GPIO_IN()==1);	//接着等待从机拉高数据线，80us
//		
//		/*开始接收40位数据*/   
//		DHT11_Data->humi_int= DHT11_ReadByte();		//湿度整数

//		DHT11_Data->humi_deci= DHT11_ReadByte();	//湿度小数

//		DHT11_Data->temp_int= DHT11_ReadByte();		//温度整数

//		DHT11_Data->temp_deci= DHT11_ReadByte();	//温度小数

//		DHT11_Data->check_sum= DHT11_ReadByte();	//检查数据
//		
//		Delay_us(50);//数据传输结束，从机拉低数据线50us
//		
//		DHT11_Mode_Out_PP();//把数据线改为输出
//		
//		DHT11_GPIO_outH();	//主机拉高数据线，准备下一次的5个字节数据传输
//		
//		//检验数据有效性
//		if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
//		{
//			return 1;
//		}
//		else
//		{
//			return 0;
//		}

//	}
//	else
//	{
//		return 0;
//	}
//}
































